import re
import json

from django.template.context_processors import csrf
from django.http import JsonResponse, HttpResponse
import pdfplumber
from pytils.translit import slugify

from main.models import Book, Quote, Note, Group, Author


def get_book(request, slug):

    """ Получаем книгу """

    def _convert_to_desired_view(book, text):
        text = text.replace('\t', ' ')[::-1]
        current_page = ''
        text = re.sub('^\d{,5}?\n', '', text)
        return (text[::-1], current_page)

    def _get_authors_name(book):
        full_name = book.author.name.split()
        name = full_name[0][0] + '. '
        surname = full_name[1]
        return name + surname

    def _get_right_pages(request, book):
        current_page = int(request.GET.get('page'))
        total_pages = book.volume
        previous_page = current_page -1 if (current_page -1) >= 0 else False
        next_page = current_page + 1
        return {'current_page': current_page,
                'total_pages': total_pages,
                'next_page': next_page,
                'previous_page': previous_page,
                'background': book.background,}

    def _get_context(request, slug, book):
        page_number = int(request.GET.get('page'))
        pages = _get_right_pages(request, book)
        path_to_book = book.file.path
        authors_name = _get_authors_name(book)
        quotes = get_information_about_book(request, book.slug)
        context = {'page_number': page_number,
                   'author': book.author.name,
                   'title': book.title,
                   'book_slug': book.slug,
                   'is_favorites': book.is_favorites,
                   'bookmark': book.bookmark,
                   'csrf_token': str(csrf(request)['csrf_token']),
                   'quotes': quotes,
                   'author_slug': book.author.slug,
                   **pages}
        with pdfplumber.open(path_to_book) as file:
            page = file.pages[page_number]
            text, current_page = _convert_to_desired_view(book, page.extract_text())
            context['text'] = text

        return context


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    book = Book.objects.get(slug=slug)

    if request.GET.get('page'):
        template = 'main/contents_of_book.html'
        context = _get_context(request, slug, book)
        return (template, context)

    else:
        template = 'main/book_big.html'
        context = {'book': book}
        return (template, context)


def get_list_of_books():

    """ Получаем список книг в нужном виде """

    def get_title(book):
        modified_book = book[0].split()
        if len(book[0]) > 23: return book[0][:19] + '...'
        else: return book[0]

    def get_description(book):
        return ' '.join(book[1].split()[:25]) + '...'

    def get_image(book):
        return 'media/' + book[3]


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    result = []
    books = Book.objects.values_list('title', 'description', 'slug', 'image').all()

    for book in books:
        title = get_title(book)
        description = get_description(book)
        image = get_image(book)
        result.append({'title': title, 'description': description, 'slug': book[2], 'image': image})

    return result


def add_bookmark(request, book, action, page):

    """ Добавляем в закладку страницу """

    book_orm = Book.objects.get(slug=book)

    if action == 'add':
        book_orm.bookmark = page
        book_orm.save()
    elif action == 'remove':
        book_orm.bookmark = 0
        book_orm.save()


def add_last_page(request, book, page_number):

    book = Book.objects.get(slug=book)
    book.last_page = page_number
    book.save()


def get_information_about_book(request, slug):

    """ Получаем информацию о книге """

    book = Book.objects.get(slug=slug)
    context = {'last_page': book.last_page,
               'volume': book.volume,
               'favorites': book.is_favorites}
    return context


def action_favorites(book, action):

    """ Выполняем какое-то действие с закладкой """

    book = Book.objects.get(slug=book)

    if action == 'remove_favorites':
        book.is_favorites = False
    elif action == 'add_favorites':
        book.is_favorites = True

    book.save()


def get_information_about_quotes(request, book_slug):

    """ Получаем информацию о цитатах """

    result = {'csrf_token': str(csrf(request)['csrf_token'])}
    quotes = {}

    book = Book.objects.get(slug=book_slug)
    quotesORM = book.quote_set.values_list('content', 'color', 'page_number', 'pk').all()

    for number, quote in enumerate(quotesORM, 0):
        quotes[number] = {'content': quote[0], 'color': quote[1],
                          'page_number': quote[2], 'id': quote[3]}

    result['quotes'] = quotes

    return result


def action_quote(request, book_slug):

    """ Совершаем какое-то действие над цитатой из книги """

    def remove_quote(request, book_slug, quote_id):

        quote = Quote.objects.get(pk=quote_id, book__slug=book_slug)
        quote.delete()


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    data = json.loads(request.body)

    if 'remove_quote_id' in data:
        remove_quote(request, book_slug, data['remove_quote_id'])

    else:
        book = Book.objects.get(slug=book_slug)
        quote = Quote.objects.create(content=data['quote'], book=book,
                                     color=data['color'], page_number=data['page_number'])

        if data['note']:
            Note.objects.create(text=data['note'], content_object=quote)


def get_information_about_note(request, book_slug):

    """ Получаем инфомрацию о примечание """

    if 'quote_id' in request.GET:

        token = str(csrf(request)['csrf_token'])
        quote_id = int(request.GET['quote_id'])
        note_text = Quote.objects.get(pk=quote_id).notes.last()

        if note_text: return JsonResponse({'note_text': note_text.text, 'token': token})
        else: return JsonResponse({'note_text': 'Примечание к этой цитате не добавлялось'})

    else:
        print('reques.get', request.GET)
        

def action_note(request, book_slug):

    if 'delete_note' in request.GET:
        quote_id = int(request.GET['delete_note'])
        quoteORM = Quote.objects.get(pk=quote_id).notes.last()
        if quoteORM: quoteORM.delete()
        return HttpResponse('')


def perform_action_on_book(request, book_slug):

    """ Выполняем какое-то действие над книгой """

    def make_book_read(book):

        """ Помечаем книгу прочитанной """

        book.is_read = True
        book.save()
        return HttpResponse('')

    def make_book_unread(book):
        """ Помечаем книгу непрочитанной """
        book.is_read = False
        book.save()
        return HttpResponse('')


    def make_book_urgent(book):
        """ Помечаем книгу неотложенной """
        book.is_defer = False
        book.save()
        return HttpResponse('')


    def make_book_defer(book):
        """ Помечаем книгу отложенной """
        book.is_defer = True
        book.save()
        return HttpResponse('')


    def delete_book(book):
        """ Удаляем книгу """
        book.delete()
        return HttpResponse('')

    def change_group_book(book, group_slug):
        """ Меняем группу книге """
        groupORM = Group.objects.get(slug=group_slug)
        book.group = groupORM
        book.save()
        return HttpResponse('')

    def change_title_of_book(book, new_name):
        """ Меняем название книги """
        book.title = new_name
        book.slug = slugify(book.title)
        book.save()
        return HttpResponse('')

    def change_description_of_book(book, new_description):
        """ Меняем описание книги """
        book.description = new_description
        book.save()
        return HttpResponse('')

    def change_author_of_book(book, author):
        """ Меняем автора книги """
        author = Author.objects.get(slug=author)
        book.author = author
        book.save()
        return HttpResponse('')

    def change_cover_of_book(request, book):
        """ Меняем обложку книги """
        image = request.FILES.getlist('file')[0]
        book.image = image
        book.save()
        return JsonResponse({'image_url': book.image.url})

    def change_background_image_of_book(request, book):
        """ Меняем фоновое изображение книги """
        background = request.FILES.getlist('file')[0]
        book.background = background
        book.save()
        return HttpResponse('')


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    book = Book.objects.get(slug=book_slug)

    if 'change_cover' in request.GET:
        return change_cover_of_book(request, book)

    if 'change_background_image' in request.GET:
        return change_background_image_of_book(request, book)

    data = json.loads(request.body)

    if 'make_book_read' in data:
        return make_book_read(book)

    if 'make_book_unread' in data:
        return make_book_unread(book)

    if 'urgent' in data:
        return make_book_urgent(book)

    if 'deferred' in data:
        return make_book_defer(book)
    
    if 'delete_book' in data:
        return delete_book(book)

    if 'group_name' in data:
        return change_group_book(book, data['group_name'])

    if 'new_book_title' in data:
        return change_title_of_book(book, data['new_book_title'])

    if 'new_book_description' in data:
        return change_description_of_book(book, data['new_book_description'])

    if 'new_author_name' in data:
        return change_author_of_book(book, data['new_author_name'])



def get_default_group():
    return Group.objects.get(title='Не указано')
